package com.app.service;

import com.app.Timer.RecommendTimer;
import com.app.model.cache.RedisKeys;
import com.app.model.cache.UserInfoToCache;
import com.app.model.main.*;
import com.app.model.response.*;
import com.app.model.solr.SolrFlag;
import com.app.model.util.ArticleFlag;
import com.app.model.util.CommonFlag;
import com.app.model.util.HotArticle;
import com.app.repository.interfaces.*;
import com.app.support.utils.RedisUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.log4j.Logger;
import org.apache.solr.common.SolrDocument;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

/**
 * Created by Lichaojie on 2017/3/26. It's a beautiful day.
 */
@Service
public class ArticleService {

    private final Logger logger = Logger.getLogger(ArticleService.class);

    @Autowired
    private ResponseService responseService;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private ImageMapper imageMapper;
    @Autowired
    private SolrService solrService;
    @Autowired
    private ApprovalMapper approvalMapper;
    @Autowired
    private CommentsOfArticleMapper commentsOfArticleMapper;
    @Autowired
    private ScanRecordMapper scanRecordMapper;
    @Autowired
    private SearchService searchService;
    @Autowired
    private RecommendTimer recommendTimer;
    @Autowired
    private TopAndCoinArticleMapper topAndCoinArticleMapper;
    @Autowired
    private RewardArticleMapper rewardArticleMapper;
    @Autowired
    private ConsumeRecordMapper consumeRecordMapper;


    @Transactional(propagation= Propagation.REQUIRED,rollbackFor = Exception.class,readOnly = false)
    public RetStatus publishArticle(String parameter) throws Exception{
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        String title = (String)paraMap.get("title");
        String content = (String)paraMap.get("content");
        String label = (String)paraMap.get("label");
        String createTime = (String)paraMap.get("createTime");
        String image = (String)paraMap.get("image");
        byte type = (byte)((int)paraMap.get("type"));

        Article article = new Article();
        article.setUserId((long) userId)
                .setTitle(title)
                .setContent(content)
                .setLabel(label)
                .setTime(createTime)
                .setType(type)
                .setImage(image)
                .setFlag((byte)1);


        if (articleMapper.insertSelective(article) != 1) { //首先将帖子插入帖子表中
            throw new Exception("数据库更新失败");
        }

        if ((type >> 3 & 0x1) == 1 || (type >> 4 & 0x1) == 1) { //如果是金币或置顶则加入金币置顶表中
            if ((type >> 3 & 0x1) == 1) {
                List<Long> tops = articleMapper.getUnexpiredArticle((byte) 8, String.valueOf(System.currentTimeMillis() -24*60*60*1000));
                int count = 0;
                byte articleType = (type >> 1 & 0x1) == 1 ? (byte) 2 : (byte) 4;
                for (long topId : tops) {
                    byte topType = (articleMapper.selectByPrimaryKey(topId).getType()>>1& 0x1) == 1 ? (byte) 2 : (byte) 4;
                    if (topType == articleType)
                        count++;
                    System.out.println(count);
                    if (count > 5) {
                        throw new Exception("置顶帖数量已满");
                    }
                }
            }
            int coin = (type >> 3 & 0x1) == 1 ? 1000 : (int) paraMap.get("coin"); //TODO 定义置顶的金币数

            long oldCoin = userInfoMapper.selectByPrimaryKey((long) userId).getCoin();
            if (oldCoin < coin) {
                //return new RetStatus().setCode(200).setMessage("金币不足");
                throw new Exception("金币不足");
            }
            if(userInfoMapper.updateUserCoin(userId, oldCoin - coin)!=1)
                throw new Exception("用户信息更新失败");
            /*if (redisUtil.exists("userInfo" + userId)) {
                UserInfo userInfo = redisUtil.get("userInfo" + userId);
                userInfo.setCoin(oldCoin - coin);
                redisUtil.set("userInfo" + userId, userInfo);
            }*/

            byte status = (type >> 3 & 0x1) == 1 ? (byte) 1 : (byte) 2;
            TopAndCoinArticle topAndCoinArticle = new TopAndCoinArticle();
            topAndCoinArticle.setArticleId(article.getId())
                    .setTime(createTime)
                    .setInitialCoin((long) coin)
                    .setRemainCoin((long) coin)
                    .setStatus(status);

            if(topAndCoinArticleMapper.insert(topAndCoinArticle)!=1)
                throw new Exception("数据库更新失败");

            //TODO 加入redis缓存，但更新要复杂一些，可能脏读，先不加
            //if (topAndCoinArticleMapper.insert(topAndCoinArticle) == 1)
            //redisUtil.set((type>>3 & 0x1) == 1?RedisKeys.TOP_ARTICLE+article.getId()
            //       :RedisKeys.COIN_ARTICLE+article.getId(),topAndCoinArticle,86400L);
        }


        if ((type >> 5 & 0x1) == 1) { //如果是悬赏则加入悬赏表中
            int reward = (int) paraMap.get("reward");

            long oldCoin = userInfoMapper.selectByPrimaryKey((long) userId).getCoin();
            if (oldCoin < reward) {
                //return new RetStatus().setCode(200).setMessage("金币不足");
                throw new Exception("金币不足");
            }
            if(userInfoMapper.updateUserCoin(userId, oldCoin - reward)!=1)
                throw new Exception("用户信息更新失败");
            /*if (redisUtil.exists("userInfo" + userId)) {
                UserInfo userInfo = redisUtil.get("userInfo" + userId);
                userInfo.setCoin(oldCoin - reward);
                redisUtil.set("userInfo" + userId, userInfo);
            }*/

            RewardArticle rewardArticle = new RewardArticle();
            rewardArticle.setArticleId(article.getId())
                    .setCoin((long) reward)
                    .setTime(article.getTime())
                    .setAdoptedTime(article.getTime());
            if(rewardArticleMapper.insertSelective(rewardArticle)!=1)
                throw new Exception("数据库更新失败");

            //TODO 将悬赏帖加入redis
            //if(rewardArticleMapper.insertSelective(rewardArticle)==1)
            //redisUtil.set(RedisKeys.REWARD_ARTICLE+article.getId(),rewardArticle,86400L);
        }

        //将文件添加进搜索服务器的操作先加入消息队列
        redisUtil.setList(RedisKeys.ARTICLETOSOLR, article);
        return responseService.doResponse(100);
    }

    @Transactional(propagation= Propagation.REQUIRED,rollbackFor = Exception.class,readOnly = false)
    public RetStatus getArticleCoin(String parameter) throws Exception{
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int articleId = (int)paraMap.get("articleId");
        int userId = (int)paraMap.get("userId");
        String time = (String)paraMap.get("time");

        ConsumeRecord record = consumeRecordMapper.selectByFromIdAndToId(new ConsumeRecord()
                .setFromId((long)articleId).setToId((long)userId));
        if(record != null)
            return new RetStatus().setCode(100).setMessage("成功").setBody("{\"coin\":0}");

        TopAndCoinArticle article = topAndCoinArticleMapper.getByArticleId((long)articleId);

        Long userGet = article.getRemainCoin()-5L >0?5L:article.getRemainCoin(); //TODO 确定每个用户可以获得多少个币
/*        if(article.getStatus() == (byte)2)
            topAndCoinArticleMapper.updateArticleType(articleId,(byte)0);*/
        if(userGet == 0L)
            return new RetStatus().setCode(100).setMessage("成功").setBody("{\"coin\":0}");
        Long remainCoin = article.getRemainCoin()-5L >0?article.getRemainCoin()-5L:0L;
        byte status = remainCoin >0 || article.getStatus() == (byte)1?article.getStatus():(byte)0;

        article.setStatus(status)
                .setRemainCoin(remainCoin);
        if(topAndCoinArticleMapper.updateByPrimaryKeySelective(article)!=1)
            throw new Exception("数据库更新失败");

        if(status == (byte)2 && remainCoin ==0L) {
            byte oldType = articleMapper.selectByPrimaryKey((long)articleId).getType();
            if(articleMapper.updateArticleType((long) articleId,(byte)(oldType-16))!=1)
                throw new Exception("数据库更新失败");
        }

        long oldCoin = userInfoMapper.selectByPrimaryKey((long)userId).getCoin();
        if(userInfoMapper.updateUserCoin(userId,oldCoin+userGet)!=1)
            throw new Exception("数据库更新失败");

        /*if(redisUtil.exists("userInfo" + userId)){
            UserInfo userInfo = redisUtil.get("userInfo" + userId);
            userInfo.setCoin(oldCoin+userGet);
            redisUtil.set("userInfo" + userId,userInfo);
        }*/


        ConsumeRecord consumeRecord = new ConsumeRecord();
        consumeRecord.setConsume(userGet)
                .setTime(time)
                .setFromId((long)articleId)
                .setToId((long)userId);

        if(consumeRecordMapper.insert(consumeRecord)!=1)
            throw new Exception("数据库更新失败");

        return new RetStatus().setCode(100).setMessage("成功").setBody("{\"coin\":"+userGet+"}");
    }

    @Transactional(propagation= Propagation.REQUIRED,rollbackFor = Exception.class,readOnly = false)
    public RetStatus getArticleReward(String parameter) throws Exception{
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }
        int articleId = (int) paraMap.get("articleId");
        int userId = (int) paraMap.get("userId");
        int commentId = (int) paraMap.get("commentId");
        String time = (String) paraMap.get("time");

        //RewardArticle article = redisUtil.get(RedisKeys.REWARD_ARTICLE+articleId);
        RewardArticle article = rewardArticleMapper.getByArticleId((long) articleId);

        long oldCoin = userInfoMapper.selectByPrimaryKey((long) userId).getCoin();
        if(userInfoMapper.updateUserCoin((long) userId, oldCoin + article.getCoin())!=1)
            throw new Exception("数据库更新失败");
        /*if (redisUtil.exists("userInfo" + userId)) {
            UserInfo userInfo = redisUtil.get("userInfo" + userId);
            userInfo.setCoin(oldCoin + article.getCoin());
            redisUtil.set("userInfo" + userId, userInfo);
        }*/


        article.setAdoptedTime(time)
                .setStatus((byte) 1)
                .setCommentId((long) commentId)
                .setUserId((long) userId);

        if(rewardArticleMapper.updateByPrimaryKeySelective(article)!=1)
            throw new Exception("数据库更新失败");

        byte oldStatus = articleMapper.selectByPrimaryKey((long) articleId).getType();
        if(articleMapper.updateArticleType(articleId, (byte) (oldStatus - 32))!=1)
            throw new Exception("数据库更新失败");
        //redisUtil.remove(RedisKeys.REWARD_ARTICLE+article.getId());

        //TODO 加入到消费表里？

        return responseService.doResponse(100);

    }

    public RetStatus getRecommend(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }
        int moreOrUpdate = (int)paraMap.get("type");

        if(moreOrUpdate == 0) { //TODO 需要确定加载更多或更新的参数 0-更新 1-加载更多
            return getUpdateWithoutUserId(parameter,ArticleFlag.RECOMMEND);
        }else{
            return getLoadMoreWithoutUserId(parameter,ArticleFlag.RECOMMEND);
        }
    }


    public RetStatus getTops(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int type = (int)paraMap.get("type");

        List<Long> tops = articleMapper.getUnexpiredArticle((byte)8,String.valueOf(System.currentTimeMillis() -24*60*60*1000));
        List<RecommendArticleResponseBody> recommendArticleResponseBodyList = new ArrayList<>();
        for(long articleId : tops) {
            Article article = articleMapper.selectByPrimaryKey(articleId);
            long userId = article.getUserId();
            UserInfoToCache userInfoToCache = new UserInfoToCache();
            String key = "userInfo" + userId ;
            if(redisUtil.exists(key)){//优先从缓存中获取用户数据
                userInfoToCache = redisUtil.get("userInfo" + userId);
            }else{
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
                userInfoToCache.setUserId(userInfo.getId())
                        .setNickName(userInfo.getNickName())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin());
            }


            RecommendArticleResponseBody recommendArticleResponseBody = new RecommendArticleResponseBody();
            recommendArticleResponseBody.setUserId(userInfoToCache.getUserId())
                    .setLabel(article.getLabel())
                    .setAvator(userInfoToCache.getAvator())
                    .setNickName(userInfoToCache.getNickName())
                    .setTitle(article.getTitle())
                    .setArticleId(article.getId())
                    .setContent(article.getContent())
                    .setTime(article.getTime())
                    .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
                    .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                    .setImage(article.getImage())
                    .type(article.getType());

            if ((type >> 1 & 0x1) == 1 && (article.getType()>>1 & 0x1) == 1) { //分享置顶
                recommendArticleResponseBodyList.add(recommendArticleResponseBody);
            }else if((type >> 2 & 0x1) == 1 && (article.getType()>>2 & 0x1) == 1){ //求助置顶
                recommendArticleResponseBodyList.add(recommendArticleResponseBody);
            }else{}
        }

        return new RetStatus().setCode(100).setMessage("成功").setBody(recommendArticleResponseBodyList);
    }


    public RetStatus getArticleDetails( String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int articleId = (int)paraMap.get("id");

        Article article = articleMapper.selectByPrimaryKey((long)articleId);
        if(article != null){
            long userId = article.getUserId();
            String avator = "";
            String nickName = "";
            String key = "userInfo" + userId;

            if(redisUtil.exists(key)){//从缓存中查找用户数据
                UserInfoToCache userInfoToCache = redisUtil.get(key);
                avator = userInfoToCache.getAvator();
                nickName = userInfoToCache.getNickName();
            }else{//若缓存没命中，到数据库中查找
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
                if(userInfo != null){
                    avator = imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin();
                    nickName = userInfo.getNickName();
                }else{
                    return responseService.doResponse(200);
                }
            }

            byte status = (byte)0;
            byte rewardFlag = (byte)0;
            byte type =  article.getType();
            if((type>>3 & 0x1) == 1|| (type>>4 & 0x1)==1){
                TopAndCoinArticle topAndCoinArticle = topAndCoinArticleMapper.getByArticleId((long)articleId);
                status = topAndCoinArticle.getRemainCoin() >0?(byte)1:(byte)0;
            }
            if((type>>5 & 0x1) == 1){
                RewardArticle rewardArticle = rewardArticleMapper.getByArticleId((long)articleId);
                rewardFlag = rewardArticle.getStatus();
            }


            ArticleDetailResponseBody articleDetailResponseBody = new ArticleDetailResponseBody();
            articleDetailResponseBody.setArticleId(article.getId())
                    .setLabel(article.getLabel())
                    .setTitle(article.getTitle())
                    .setContent(article.getContent())
                    .setTime(article.getTime())
                    .setUserId(userId)
                    .setAvator(avator)
                    .setNickName(nickName)
                    .type(article.getType())
                    .status(status)
                    .adoptFlag(rewardFlag);

            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(articleDetailResponseBody);
            return retStatus;

        }else{
            return responseService.doResponse(200);
        }
    }

    public RetStatus doSearch(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        String keywords = (String)paraMap.get("keyword");
        String labelStr = (String)paraMap.get("label");
        int type = (int)paraMap.get("type");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");
        int iid = (int)paraMap.get("userId");

        //添加搜索记录
        searchService.addSearchRecord(keywords,labelStr,Long.toString(System.currentTimeMillis()), CommonFlag.ARTICLE,(long)iid);

        if(page < 0) page = 0;

        List resultList = null;

        String queryString;
        if(labelStr.equals("") && keywords.equals("")){
            return responseService.doResponse(220);
        }else {
            String[] labels = labelStr.split(",");
            queryString = keywords;
            for(String str : labels){
                queryString += (" " + str);
            }
        }

        // logger.info("queryString : " + queryString);

        resultList = solrService.queryWithFilter(queryString, SolrFlag.ARTICLE,page,number,(byte)type);

        if(resultList.size() == 0 && page == 0){
            return responseService.doResponse(214);
        }else if(resultList.size() == 0 && page != 0){
            return responseService.doResponse(216);
        }else {
            List<SearchArticleResponseBody> articleList = new ArrayList<>();
            for(Object object : resultList){
                SolrDocument solrDocument = (SolrDocument)object;

                long articleId = Long.parseLong((String)solrDocument.getFieldValue("id"));
                Article article = articleMapper.selectByPrimaryKey(articleId);

                long userId = article.getUserId();
                UserInfoToCache userInfoToCache = new UserInfoToCache();
                String key = "userInfo" + userId ;
                if(redisUtil.exists(key)){//优先从缓存中获取用户数据
                    userInfoToCache = redisUtil.get("userInfo" + userId);
                }else{
                    UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
                    userInfoToCache.setUserId(userInfo.getId())
                            .setNickName(userInfo.getNickName())
                            .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin());
                }


                long approvalNum = approvalMapper.getApprovalNumber(articleId, CommonFlag.ARTICLE);
                long commentsNumber = commentsOfArticleMapper.getCommentsNumber(articleId);

                SearchArticleResponseBody articleResponseBody = new SearchArticleResponseBody();
                articleResponseBody.setUserId(userId)
                        .setNickName(userInfoToCache.getNickName())
                        .setAvator(userInfoToCache.getAvator())
                        .setArticleId(articleId)
                        .setTitle(article.getTitle())
                        .setContent(article.getContent())
                        .setTime(article.getTime())
                        .setApprovalNum((int)approvalNum)
                        .setCommentNum((int)commentsNumber)
                        .setLabel(article.getLabel())
                        .setImage(article.getImage());
                articleList.add(articleResponseBody);

            }
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(articleList);
            return retStatus;
        }
    }

    public RetStatus doScanRecord( String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int articleId = (int)paraMap.get("articleId");
        String endTime = (String)paraMap.get("endTime");
        String spentTime = (String)paraMap.get("spentTime");

        ScanRecord scanRecord = new ScanRecord();
        scanRecord.setUserId((long) userId)
                .setArticleId((long) articleId)
                .setEndTime(endTime)
                .setSpentTime(spentTime);
        if(scanRecordMapper.insert(scanRecord) == 1){
            return responseService.doResponse(100);
        }else {
            return responseService.doResponse(200);
        }
    }

    public RetStatus getUpdate(String parameter,byte type){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int lastId = (int)paraMap.get("lastId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");

        List<MyArticleResponseBody> myArticleResponseBodyList = new ArrayList<>();

        List<Article> list;
        if(page == 0){//第一次进入此页面
            list = articleMapper.getListOrderedByIdDESC((long)userId,articleMapper.getMaxId() + 1,page,number,type);
        }else {
            list = articleMapper.getListOrderedByIdASC((long) userId, (long) lastId, page, number, type);
        }

        if(list != null && list.size() > 0){
            UserInfo userInfo = userInfoMapper.selectByPrimaryKey(list.get(0).getUserId());
            for(Article article : list){
                MyArticleResponseBody myArticleResponseBody = new MyArticleResponseBody();
                myArticleResponseBody.setUserId(userInfo.getId())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setLabel(userInfo.getLabel())
                        .setNickName(userInfo.getNickName())
                        .setArticleId(article.getId())
                        .setTitle(article.getTitle())
                        .setContent(article.getContent())
                        .setTime(article.getTime())
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
                        .setImage(article.getImage());
                myArticleResponseBodyList.add(myArticleResponseBody);
            }
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(myArticleResponseBodyList);
            return retStatus;
        }else {
            return responseService.doResponse(216);
        }
    }

    public RetStatus getLoadMore(String parameter,byte type){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int lastId = (int)paraMap.get("lastId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");

        List<MyArticleResponseBody> myArticleResponseBodyList = new ArrayList<>();

        List<Article> list = articleMapper.getListOrderedByIdDESC((long) userId, (long) lastId, page, number, type);

        if(list != null && list.size() > 0){
            UserInfo userInfo = userInfoMapper.selectByPrimaryKey(list.get(0).getUserId());
            for(Article article : list){
                MyArticleResponseBody myArticleResponseBody = new MyArticleResponseBody();
                myArticleResponseBody.setUserId(userInfo.getId())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setLabel(userInfo.getLabel())
                        .setNickName(userInfo.getNickName())
                        .setArticleId(article.getId())
                        .setTitle(article.getTitle())
                        .setContent(article.getContent())
                        .setTime(article.getTime())
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
                        .setImage(article.getImage());
                myArticleResponseBodyList.add(myArticleResponseBody);
            }
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(myArticleResponseBodyList);
            return retStatus;
        }else {
            return responseService.doResponse(216);
        }
    }

    public RetStatus getUpdateWithoutUserId(String parameter,byte type){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int lastId = (int)paraMap.get("lastId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");

        List<RecommendArticleResponseBody> recommendArticleResponseBodyList = new ArrayList<>();

        List<Article> list ;
        if(page == 0){//第一次进入此页面
            list = articleMapper.getListOrderedByIdWithoutUserIdDESC(articleMapper.getMaxId() + 1,page,number,type);
        }else {
            list = articleMapper.getListOrderedByIdWithoutUserIdASC((long)lastId,page,number,type);
        }

        logger.info("list.size() : " + list.size());
        logger.info("articleMapper.getMaxId() : " + articleMapper.getMaxId());

        if(list != null && list.size() > 0){
            for (Article article : list){
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());
                RecommendArticleResponseBody recommendArticleResponseBody = new RecommendArticleResponseBody();
                recommendArticleResponseBody.setUserId(userInfo.getId())
                        .setLabel(article.getLabel())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setNickName(userInfo.getNickName())
                        .setTitle(article.getTitle())
                        .setArticleId(article.getId())
                        .setContent(article.getContent())
                        .setTime(article.getTime())
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setImage(article.getImage())
                        .type(article.getType());
                recommendArticleResponseBodyList.add(recommendArticleResponseBody);
            }
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(recommendArticleResponseBodyList);
            return retStatus;
        }else {
            return responseService.doResponse(216);
        }
    }

    public RetStatus getLoadMoreWithoutUserId(String parameter,byte type){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int lastId = (int)paraMap.get("lastId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");

        List<RecommendArticleResponseBody> recommendArticleResponseBodyList = new ArrayList<>();

        List<Article> list = articleMapper.getListOrderedByIdWithoutUserIdDESC((long) lastId, page, number, type);

        if(list != null && list.size() > 0){
            for (Article article : list){
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());
                RecommendArticleResponseBody recommendArticleResponseBody = new RecommendArticleResponseBody();
                recommendArticleResponseBody.setUserId(userInfo.getId())
                        .setNickName(userInfo.getNickName())
                        .setLabel(article.getLabel())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setArticleId(article.getId())
                        .setTitle(article.getTitle())
                        .setContent(article.getContent())
                        .setTime(article.getTime())
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
                        .setImage(article.getImage())
                        .type(article.getType());
                recommendArticleResponseBodyList.add(recommendArticleResponseBody);
            }
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(recommendArticleResponseBodyList);
            return  retStatus;
        }else {
            return responseService.doResponse(216);
        }
    }

    //推荐分享贴（加载更多） 第一版
    @Deprecated
    public RetStatus getShareRecommendLoadMore(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");

        List<HotArticle> hotArticleList = redisUtil.get(RedisKeys.RECOMMEND_ARTICLE_LIST);
        if(hotArticleList == null){
            recommendTimer.hotArticleTimer();
            hotArticleList = redisUtil.get(RedisKeys.RECOMMEND_ARTICLE_LIST);
        }

        logger.info("hotArticleList.size() : " + hotArticleList.size());

        List<HotArticle> resultList = new ArrayList<>();
        int start = page * number > hotArticleList.size() ? hotArticleList.size(): page * number;
        int end = page * number + number > hotArticleList.size() ? hotArticleList.size() : page * number + number;
        for(int i = start; i < end; i ++){
            resultList.add(hotArticleList.get(i));
        }


        List<RecommendArticleResponseBody> result = new ArrayList<>();
        if(resultList.size() > 0){
            for (HotArticle hotArticle : resultList){
                Article article = articleMapper.selectByPrimaryKey(hotArticle.getId());
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());

                RecommendArticleResponseBody recommendArticleResponseBody = new RecommendArticleResponseBody();
                recommendArticleResponseBody.setUserId(userInfo.getId())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setNickName(userInfo.getNickName())
                        .setLabel(userInfo.getLabel())
                        .setArticleId(article.getId())
                        .setTitle(article.getTitle())
                        .setContent(article.getContent())
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(),CommonFlag.ARTICLE))
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setTime(article.getTime());

                result.add(recommendArticleResponseBody);
            }
        }

        if(result.size() > 0){
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(result);
            return retStatus;
        }else {
            return responseService.doResponse(216);
        }

    }

    @Deprecated
    public RetStatus getShareRecommendUpdate(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");

        long time2 = System.currentTimeMillis();
        long time1 = time2 - 7*24*60*60*1000;

        //7天内的帖子
        List<Article> idList1;

        List<HotArticle> hotArticleList1;

        idList1 = articleMapper.getIdListBetween(time1 + "",time2 + "", ArticleFlag.SHARE);


        hotArticleList1 = new ArrayList<>();
        for (Article article : idList1){
            HotArticle hotArticle = new HotArticle();
            long id = article.getId();
            long approvalNum = approvalMapper.getApprovalNumber(id, CommonFlag.ARTICLE);
            long commentsNum = commentsOfArticleMapper.getCommentsNumber(id);
            long scanNum = scanRecordMapper.getScanNumber(id);

            hotArticle.setApprovalNum(approvalNum)
                    .setCommentsNum(commentsNum)
                    .setScanNum(scanNum)
                    .setId(id)
                    .setHotValue(scanNum + 4 * approvalNum + 16 * commentsNum);
            hotArticleList1.add(hotArticle);
        }

//        for (HotArticle hotArticle : hotArticleList1){
//            System.out.print(hotArticle.getHotValue() + " ");
//        }

        Collections.sort(hotArticleList1);//将7天内所有帖子按HOT值进行排序

//        for (HotArticle hotArticle : hotArticleList1){
//            System.out.print(hotArticle.getHotValue() + " ");
//        }



        List<HotArticle> resultList = new ArrayList<>();

        //每天固定推荐的分享贴
        List<HotArticle> hotArticleList2 = redisUtil.get(RedisKeys.RECOMMEND_ARTICLE_LIST);
        if(hotArticleList2 == null){
            recommendTimer.hotArticleTimer();
            hotArticleList2 = redisUtil.get(RedisKeys.RECOMMEND_ARTICLE_LIST);
        }
        HotArticle hotArticle = new HotArticle();
        if(hotArticleList2.size() > 0){
            hotArticle = hotArticleList2.get(0);//每天固定条数中HOT值最大的帖子
        }else {
            hotArticle.setHotValue(0);
        }


        //从最新的计算结果中将每天固定部分的帖子除去
        for (HotArticle hot : hotArticleList1){
            if (hot.getHotValue() >= hotArticle.getHotValue()){//HOT值须比之前最大的HOT值更大
                if(!hotArticleList2.contains(hot)){//且该帖子不在每天固定推荐的帖子中
                    resultList.add(hot);
                }
            }else {
                break;
            }
        }

        List<HotArticle> result1 = new ArrayList<>();
        String k = RedisKeys.RECOMMEND_SHARE_ARTICLE_UPDATE_HISTORY + userId;
        if(redisUtil.exists(k)){
            List<Long> idList = redisUtil.get(k);
            for(HotArticle hot : resultList){
                if(!idList.contains(hot.getId())){
                    result1.add(hot);
                }
            }
        }


        List<RecommendArticleResponseBody> result = new ArrayList<>();
        if(resultList.size() > 0){
            for (HotArticle hot : result1){
                Article article = articleMapper.selectByPrimaryKey(hot.getId());
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());

                RecommendArticleResponseBody recommendArticleResponseBody = new RecommendArticleResponseBody();
                recommendArticleResponseBody.setUserId(userInfo.getId())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setNickName(userInfo.getNickName())
                        .setLabel(userInfo.getLabel())
                        .setArticleId(article.getId())
                        .setTitle(article.getTitle())
                        .setContent(article.getContent())
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(),CommonFlag.ARTICLE))
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setTime(article.getTime());

                result.add(recommendArticleResponseBody);
            }
        }

        RetStatus retStatus = new RetStatus();
        //返回此次刷新得到的数据
        int size = result.size();
        if(size == 0){
            return responseService.doResponse(216);
        }else if(size > 0 && size <= number){
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(result);
        }else{
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(result.subList(0,10));
        }

        //每次刷新更新缓存
        String key = RedisKeys.RECOMMEND_SHARE_ARTICLE_UPDATE_HISTORY + userId;
        List<Long> idList = new ArrayList<>();
        if(redisUtil.exists(key)){
            idList = redisUtil.get(key);
            redisUtil.remove(key);
        }
        for(HotArticle hot : result1){
            idList.add(hot.getId());
        }
        redisUtil.set(key,idList);

        return retStatus;
    }

    public RetStatus doDelete(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int articleId = (int)paraMap.get("articleId");

        if(articleMapper.updateFlagByPrimaryKey((long)articleId) == 1){
            Map<String,Long> map = new HashMap<>();
            map.put("articleId",(long)articleId);

            //同时删除搜索服务器中该帖子数据
            solrService.delete(Integer.toString(articleId), SolrFlag.ARTICLE);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("articleId",articleId);
            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(map);
            return retStatus;
        }else {
            return responseService.doResponse(200);
        }
    }

    public RetStatus getApprovalAndCommentsNumber(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        String ids = (String)paraMap.get("ids");
        String[] idArray = ids.split(",");
        List<JSONObject> result = new ArrayList<>();
        for (String idStr : idArray){
            long id = Long.parseLong(idStr);

            long approvalNum = 0;
            String appvoralKey = RedisKeys.APPROVAL_NUMBER.ARTICLE + id;
            if(redisUtil.exists(appvoralKey)){
                approvalNum = ((Integer)redisUtil.get(appvoralKey)).longValue();
            }

            long commentsNum = 0;
            String commentsKey = RedisKeys.COMMENTS_NUMBER_OF_ARTICLE + id;
            if(redisUtil.exists(commentsKey)){
                commentsNum = ((Integer)redisUtil.get(commentsKey)).longValue();
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("articleId",id);
            jsonObject.put("approvalNum",approvalNum);
            jsonObject.put("commentsNum",commentsNum);
            result.add(jsonObject);
        }

        RetStatus retStatus = new RetStatus();
        retStatus.setCode(100)
                .setMessage(RetCode.getMessage(100))
                .setBody(result);

        return retStatus;
    }
}
